#ifndef HELPERS_H

#include <stdio.h>
#include <cstring>
#include <iostream>
using std::cin;
using std::cout;

#define ERR_ON(cond) fprintf(stderr, "ERROR %d: %s\n  file: '%s' line: %d", \
		      errno, strerror(errno), __FILE__, __LINE__)

int parseIoOpts(int argc, char *argv[], char **fin, char **fout) {
  *fout = *fin = 0;
  
  int opt;
  while ((opt = getopt(argc, argv, "-:o:")) != -1) {
    switch (opt) {
      case 'o':
	if (*fout) return 1;
	*fout = optarg;
	break;
      case 1:
	if (*fout) return 1;
	*fin = optarg;
	break;
      default:
	return 2;
    }
  }
  
  return 0;
}

int reopenIO(char *fin, char *fout) {
  if (fin != 0) {
    ERR_ON (freopen(fin, "r", stdin) == 0);
    return 1;
  }
  
  if (fout != 0) {
    ERR_ON (freopen(fout, "w", stdout) == 0);
    return 2;
  }
  
  return 0;
}

int reopenIO(int argc, char *argv[]) {
  char *fin, *fout;
  
  parseIoOpts(argc, argv, &fin, &fout);
  
  return reopenIO(fin, fout);
}

int paramsIO(int argc, char *argv[], const char *usage) {
  char *fin, *fout;
  int fd;
  
  if (parseIoOpts(argc, argv, &fin, &fout) || !fin) {
    printf("Usage: %s\n", usage);
    exit(1);
  }
  
  if (fout != 0 && !freopen(fout, "w", stdout)) {
    printf("can't open file '%s': ", fout);
    perror(0);
    exit(2);
  }
  
  if( ! (fd = open(fin, O_RDONLY)) ) {
    printf("can't open file '%s': ", fout);
    perror(0);
    exit(3);
  }
  
  return fd;
}


inline int fileSize(int fd) {
  struct stat s;
  fstat(fd, &s);
  
  return s.st_size;
}

#endif /*HELPERS_H*/